package com.pai4j.act.service;
import com.pai4j.common.constants.ResourceBehaviorConstants;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

@Component
public class ResourceBehaviorFactory implements InitializingBean , ApplicationContextAware {
    /**
     * 应用上下文对象，用于获取Spring容器中的Bean实例
     */
    private ApplicationContext applicationContext;
    
    /**
     * 行为服务映射表，存储行为类型与对应服务实现的映射关系
     */
    private static final Map<String, AbstractResourceBehaviorService> serviceMap = new HashMap<>();

    /**
     * 初始化Bean属性后的回调方法，用于初始化服务映射表
     * @throws Exception 初始化过程中可能抛出的异常
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        this.initServiceMap();
    }

    /**
     * 初始化服务映射表，将各种行为类型映射到对应的服务实现
     * LIKE和COLLECT行为映射到双向行为服务
     * SHARE和VIEW行为映射到单向行为服务
     */
    private void initServiceMap() {

        serviceMap.put(ResourceBehaviorConstants.BehaviorType.LIKE.name(), applicationContext.getBean(TwoWayResourceBehaviorService.class));
        serviceMap.put(ResourceBehaviorConstants.BehaviorType.COLLECT.name(), applicationContext.getBean(TwoWayResourceBehaviorService.class));
        serviceMap.put(ResourceBehaviorConstants.BehaviorType.SHARE.name(), applicationContext.getBean(OneWayResourceBehaviorService.class));
        serviceMap.put(ResourceBehaviorConstants.BehaviorType.VIEW.name(), applicationContext.getBean(OneWayResourceBehaviorService.class));
        serviceMap.put(ResourceBehaviorConstants.BehaviorType.RECOMMEND.name(), applicationContext.getBean(OneWayResourceBehaviorService.class));
    }

    /**
     * 根据行为类型获取对应的行为服务实例
     * @param behaviorType 行为类型字符串
     * @return 对应的抽象资源行为服务实例
     * @throws IllegalArgumentException 当不支持的行为类型时抛出异常
     */
    public static AbstractResourceBehaviorService getService(String behaviorType) {

        AbstractResourceBehaviorService abstractResourceBehaviorService = serviceMap.get(behaviorType);
        Assert.notNull(abstractResourceBehaviorService, "不支持的互动行为");
        abstractResourceBehaviorService.setBehaviorType(behaviorType);
        return abstractResourceBehaviorService;
    }

    /**
     * 设置应用上下文，Spring容器回调方法
     * @param applicationContext Spring应用上下文对象
     * @throws BeansException 设置过程中可能抛出的Bean异常
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
